if not DpsDashboard then
  DpsDashboard = { };
end

--**************************** Empty ***************************************
DpsDashboard.GetEmpty = function()
  return "";
end
DPS_DASHBOARD_STAT_REGISTER["empty"] = DpsDashboard.GetEmpty;
DPS_DASHBOARD_STAT_TYPE_REGISTER["empty"] = DPS_DASHBOARD_UPDATE_NEVER;


--**************************** Crit ***************************************
DpsDashboard.GetMeleeCrit = function()
  return DPSDASHBOARD_STAT_TEXT["meleecrit"]..format(": %.2f", GetCritChance());
end
DPS_DASHBOARD_STAT_REGISTER["meleecrit"] = DpsDashboard.GetMeleeCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["meleecrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetRangedCrit = function()
  return DPSDASHBOARD_STAT_TEXT["rangedcrit"]..format(": %.2f", GetRangedCritChance());
end
DPS_DASHBOARD_STAT_REGISTER["rangedcrit"] = DpsDashboard.GetRangedCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["rangedcrit"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Attack Power ***************************************
DpsDashboard.GetMeleeAttackPower = function()
  local baseAp, posAp, negAp = UnitAttackPower("player");
  return DPSDASHBOARD_STAT_TEXT["meleeattackpower"]..format(": %d", baseAp + posAp - negAp);
end
DPS_DASHBOARD_STAT_REGISTER["meleeattackpower"] = DpsDashboard.GetMeleeAttackPower;
DPS_DASHBOARD_STAT_TYPE_REGISTER["meleeattackpower"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetRangedAttackPower = function()
  local baseAp, posAp, negAp = UnitRangedAttackPower("player");
  return DPSDASHBOARD_STAT_TEXT["rangedattackpower"]..format(": %d", baseAp + posAp - negAp);
end
DPS_DASHBOARD_STAT_REGISTER["rangedattackpower"] = DpsDashboard.GetRangedAttackPower;
DPS_DASHBOARD_STAT_TYPE_REGISTER["rangedattackpower"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Spell Damage ***************************************
DpsDashboard.GetHolyDamage = function()
  return DPSDASHBOARD_STAT_TEXT["holydamage"]..format(": %d", GetSpellBonusDamage(2));
end
DPS_DASHBOARD_STAT_REGISTER["holydamage"] = DpsDashboard.GetHolyDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["holydamage"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetFireDamage = function()
  return DPSDASHBOARD_STAT_TEXT["firedamage"]..format(": %d", GetSpellBonusDamage(3));
end
DPS_DASHBOARD_STAT_REGISTER["firedamage"] = DpsDashboard.GetFireDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["firedamage"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetNatureDamage = function()
  return DPSDASHBOARD_STAT_TEXT["naturedamage"]..format(": %d", GetSpellBonusDamage(4));
end
DPS_DASHBOARD_STAT_REGISTER["naturedamage"] = DpsDashboard.GetNatureDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["naturedamage"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetFrostDamage = function()
  return DPSDASHBOARD_STAT_TEXT["frostdamage"]..format(": %d", GetSpellBonusDamage(5));
end
DPS_DASHBOARD_STAT_REGISTER["frostdamage"] = DpsDashboard.GetFrostDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["frostdamage"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetShadowDamage = function()
  return DPSDASHBOARD_STAT_TEXT["shadowdamage"]..format(": %d", GetSpellBonusDamage(6));
end
DPS_DASHBOARD_STAT_REGISTER["shadowdamage"] = DpsDashboard.GetShadowDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["shadowdamage"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetArcaneDamage = function()
  return DPSDASHBOARD_STAT_TEXT["arcanedamage"]..format(": %d", GetSpellBonusDamage(7));
end
DPS_DASHBOARD_STAT_REGISTER["arcanedamage"] = DpsDashboard.GetArcaneDamage;
DPS_DASHBOARD_STAT_TYPE_REGISTER["arcanedamage"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Spell Crits ***************************************
DpsDashboard.GetHolyCrit = function()
  return DPSDASHBOARD_STAT_TEXT["holycrit"]..format(": %.2f", GetSpellCritChance(2));
end
DPS_DASHBOARD_STAT_REGISTER["holycrit"] = DpsDashboard.GetHolyCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["holycrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetFireCrit = function()
  return DPSDASHBOARD_STAT_TEXT["firecrit"]..format(": %.2f", GetSpellCritChance(3));
end
DPS_DASHBOARD_STAT_REGISTER["firecrit"] = DpsDashboard.GetFireCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["firecrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetNatureCrit = function()
  return DPSDASHBOARD_STAT_TEXT["naturecrit"]..format(": %.2f", GetSpellCritChance(4));
end
DPS_DASHBOARD_STAT_REGISTER["naturecrit"] = DpsDashboard.GetNatureCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["naturecrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetFrostCrit = function()
  return DPSDASHBOARD_STAT_TEXT["frostcrit"]..format(": %.2f", GetSpellCritChance(5));
end
DPS_DASHBOARD_STAT_REGISTER["frostcrit"] = DpsDashboard.GetFrostCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["frostcrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetShadowCrit = function()
  return DPSDASHBOARD_STAT_TEXT["shadowcrit"]..format(": %.2f", GetSpellCritChance(6));
end
DPS_DASHBOARD_STAT_REGISTER["shadowcrit"] = DpsDashboard.GetShadowCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["shadowcrit"] = DPS_DASHBOARD_UPDATE_STATS;


DpsDashboard.GetArcaneCrit = function()
  return DPSDASHBOARD_STAT_TEXT["arcanecrit"]..format(": %.2f", GetSpellCritChance(7));
end
DPS_DASHBOARD_STAT_REGISTER["arcanecrit"] = DpsDashboard.GetArcaneCrit;
DPS_DASHBOARD_STAT_TYPE_REGISTER["arcanecrit"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Healing ***************************************
DpsDashboard.GetHealing = function()
  return DPSDASHBOARD_STAT_TEXT["healing"]..format(": %d", GetSpellBonusHealing());
end
DPS_DASHBOARD_STAT_REGISTER["healing"] = DpsDashboard.GetHealing;
DPS_DASHBOARD_STAT_TYPE_REGISTER["healing"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** DPS ***************************************
DpsDashboard.GetDPS = function()
  return DPSDASHBOARD_STAT_TEXT["dps"]..format(": %d", DpsDashboard.dps);
end
DPS_DASHBOARD_STAT_REGISTER["dps"] = DpsDashboard.GetDPS;
DPS_DASHBOARD_STAT_TYPE_REGISTER["dps"] = DPS_DASHBOARD_UPDATE_TIMED;


--**************************** HPS ***************************************
DpsDashboard.GetHPS = function()
  return DPSDASHBOARD_STAT_TEXT["hps"]..format(": %d", DpsDashboard.hps);
end
DPS_DASHBOARD_STAT_REGISTER["hps"] = DpsDashboard.GetHPS;
DPS_DASHBOARD_STAT_TYPE_REGISTER["hps"] = DPS_DASHBOARD_UPDATE_TIMED;


--**************************** Mana Regen ***************************************
DpsDashboard.GetManaRegen = function()
  local base, casting = GetManaRegen();
  local amount = 0;
  if UnitCastingInfo("player") then
    amount = floor( casting * 5 );
  else
    amount = floor( base * 5 );
  end
  return DPSDASHBOARD_STAT_TEXT["mp5"]..format(": %.2f", amount);
end
DPS_DASHBOARD_STAT_REGISTER["mp5"] = DpsDashboard.GetManaRegen;
DPS_DASHBOARD_STAT_TYPE_REGISTER["mp5"] = DPS_DASHBOARD_UPDATE_TIMED;


--**************************** Dodge ***************************************
DpsDashboard.GetDodge = function()
  return DPSDASHBOARD_STAT_TEXT["dodge"]..format(": %.2f", GetDodgeChance());
end
DPS_DASHBOARD_STAT_REGISTER["dodge"] = DpsDashboard.GetDodge;
DPS_DASHBOARD_STAT_TYPE_REGISTER["dodge"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Avoidance ***************************************
local levelDiff, avoidance, dodge, parry, defense, otherDefense;
DpsDashboard.GetAvoidance = function()
  defense, otherDefense = UnitDefense("player");
  defense = defense + otherDefense;
  otherDefense = DpsDashboard.TargetLevel * 5;
  defense = defense - otherDefense;
  if defense > 0 then
    defense = defense * .04;
  else
    defense = defense * .02;
  end
  
  levelDiff = DpsDashboard.TargetLevel - UnitLevel("player");
  if levelDiff > 0 then
    levelDiff = levelDiff * .2;
  else
    levelDiff = 0;
  end
  
  avoidance = 5 + defense;
  dodge = GetDodgeChance();
  parry = GetParryChance();
  if dodge > 0 then
    avoidance = avoidance + dodge - levelDiff;
  end
  if parry > 0 then
    avoidance = avoidance + parry - levelDiff;
  end
  return DPSDASHBOARD_STAT_TEXT["avoidance"]..format(": %.2f", avoidance);
end
DPS_DASHBOARD_STAT_REGISTER["avoidance"] = DpsDashboard.GetAvoidance;
DPS_DASHBOARD_STAT_TYPE_REGISTER["avoidance"] = DPS_DASHBOARD_UPDATE_STATS;


--**************************** Armor Penetration ***************************************
DpsDashboard.GetArmorPenetration = function()
  return DPSDASHBOARD_STAT_TEXT["armorpen"]..format(": %.2f", GetArmorPenetration());
end
DPS_DASHBOARD_STAT_REGISTER["armorpen"] = DpsDashboard.GetArmorPenetration;
DPS_DASHBOARD_STAT_TYPE_REGISTER["armorpen"] = DPS_DASHBOARD_UPDATE_STATS;
